﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceProcess;
using PSE.ProcessManager.Common.Gateway;
using System.ServiceModel;
using System.Configuration;
using System.Threading;
using PSE.ProcessManager.Common.Configuration;
using PSE.Framework.Configuration;
using PSE.ProcessManager.Entity;

namespace PSE.ProcessManager.ServiceManager
{
    public class ServiceManager
    {
        public const string SERVICE_NAME = "PSEProcessManager";

        public ServiceManager()
            : this(ApplicationConfiguration.CurrentSystem)
        {
        }

        public ServiceManager(SystemComponent system)
            : this(ApplicationConfiguration.CurrentSystem, "localhost")
        {
        }

        public ServiceManager(string serverName)
            : this(ApplicationConfiguration.CurrentSystem, serverName)
        {
        }

        public ServiceManager(SystemComponent system, string serverName)
        {
            InteligenceManagerConfigurationSection section = ApplicationConfiguration.GetCurrent(system).GetSection<InteligenceManagerConfigurationSection>("inteligenceManagerConfiguration");
            
            UriBuilder address = new UriBuilder(section.InteligenceManagerAddress);
            address.Host = serverName;

            this.Address = address.Uri;
        }

        public ServiceManager(Uri address)
        {
            this.Address = address;
        }

        public Uri Address { get; private set; }

        #region Windows Service

        /// <summary>
        /// Iniciar o serviço do process manager, aguardando por tempo indeterminado.
        /// </summary>
        /// <returns></returns>
        public bool Start()
        {
            return this.Start(null);
        }

        /// <summary>
        /// Iniciar o serviço do process manager aguardando por um período de tempo determinado
        /// </summary>
        /// <param name="timeout">Tempo máximo de espera. caso sej informado null, irá esperar até que o serviço seja iniciado.</param>
        /// <returns></returns>
        public bool Start(TimeSpan? timeout)
        {
            bool started = false;

            using (ServiceController controller = new ServiceController(SERVICE_NAME))
            {
                if (controller.Status == ServiceControllerStatus.Stopped)
                {
                    controller.Start();

                    controller.Refresh();

                    DateTime utcNow = DateTime.UtcNow;

                    while (controller.Status != System.ServiceProcess.ServiceControllerStatus.Running)
                    {
                        Thread.Sleep(250);
                        controller.Refresh();

                        if (timeout.HasValue && (DateTime.UtcNow - utcNow) > timeout)
                        {
                            throw new System.ServiceProcess.TimeoutException();
                        }

                        if (controller.Status == ServiceControllerStatus.Stopped)
                            break;
                    }

                    started = true;
                }

                //started = (controller.Status == System.ServiceProcess.ServiceControllerStatus.Running);
            }

            return started;
        }

        /// <summary>
        /// Parar o serviço do process manager, aguardando por tempo indeterminado.
        /// </summary>
        /// <returns></returns>
        public bool Stop()
        {
            return this.Stop(null);
        }

        /// <summary>
        /// Parar o serviço do process manager aguardando por um período de tempo determinado
        /// </summary>
        /// <param name="timeout">Tempo máximo de espera. caso sej informado null, irá esperar até que o serviço seja finalizado.</param>
        /// <returns></returns>
        public bool Stop(TimeSpan? timeout)
        {
            bool stopped = false;

            using (ServiceController controller = new ServiceController(SERVICE_NAME))
            {
                if (controller.Status == ServiceControllerStatus.Running)
                {
                    controller.Stop();

                    controller.Refresh();

                    if (timeout.HasValue)
                        controller.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped, timeout.Value);
                    else
                        controller.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);

                    stopped = true;
                }

                //stopped = (controller.Status == System.ServiceProcess.ServiceControllerStatus.Stopped);
            }

            return stopped;
        }

        /// <summary>
        /// Reiniciar o serviço do process manager, aguardando por tempo indeterminado.
        /// </summary>
        /// <returns></returns>
        public bool Restart()
        {
            return this.Restart(null);
        }

        /// <summary>
        /// Reiniciar o serviço do process manager aguardando por um período de tempo determinado
        /// </summary>
        /// <param name="timeout">Tempo máximo de espera. caso seja informado null, irá esperar indefinidamente.</param>
        /// <returns></returns>
        public bool Restart(TimeSpan? timeout)
        {
            this.Stop(timeout);
            return this.Start(timeout);
        }

        /// <summary>
        /// Recupera o status do windows service
        /// </summary>
        /// <returns></returns>
        public ServiceControllerStatus GetStatus()
        {
            using (ServiceController controller = new ServiceController(SERVICE_NAME))
            {
                return controller.Status;
            }
        }

        #endregion

        #region Products

        private IInteligenceManagerService GetInteligenceManagerServiceProxy()
        {
            EndpointAddress endpoint = new EndpointAddress(this.Address);
            IInteligenceManagerService proxy = null;

            //BindingConfiguration
            string schema = endpoint.Uri.Scheme;

            switch (schema.ToUpper())
            {
                case "NET.TCP":
                    NetTcpBinding tcpBinding = new NetTcpBinding(SecurityMode.None);
                    proxy = ChannelFactory<IInteligenceManagerService>.CreateChannel(tcpBinding, endpoint);
                    break;
                case "NET.PIPE":
                    NetNamedPipeBinding namedPipeBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
                    proxy = ChannelFactory<IInteligenceManagerService>.CreateChannel(namedPipeBinding, endpoint);
                    break;
            }

            return proxy;
        }

        /// <summary>
        /// Inicia todas as instâncias do produto
        /// </summary>
        /// <param name="productKey">Nome do produto</param>
        /// <returns></returns>
        public bool StartProduct(string productKey)
        {
            if (string.IsNullOrEmpty(productKey))
                throw new ArgumentNullException("productKey");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.StartProduct(productKey);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch 
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Para todas as instâncias do produto
        /// </summary>
        /// <param name="productKey">Nome do produto</param>
        /// <returns></returns>
        public bool StopProduct(string productKey)
        {
            if (string.IsNullOrEmpty(productKey))
                throw new ArgumentNullException("productKey");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.StopProduct(productKey);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Reinicia todas as instâncias do produto
        /// </summary>
        /// <param name="productKey">Nome do produto</param>
        /// <returns></returns>
        public bool RestartProduct(string productKey)
        {
            if (string.IsNullOrEmpty(productKey))
                throw new ArgumentNullException("productKey");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.RestartProduct(productKey);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Cria um produto
        /// </summary>
        /// <param name="productName">Nome do produto</param>
        /// <returns>true se conseguiu criar o produto, false se o produto já existe</returns>
        public bool AddProduct(string productName)
        {
            if (string.IsNullOrEmpty(productName))
                throw new ArgumentNullException("productName");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.AddProduct(productName);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Exclui um produto
        /// </summary>
        /// <param name="productName">Nome do produto</param>
        /// <returns>true se conseguiu excluir o produto, false se o produto não existe</returns>
        public bool RemoveProduct(string productName)
        {
            if (string.IsNullOrEmpty(productName))
                throw new ArgumentNullException("productName");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.RemoveProduct(productName);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Lista todos os produtos instalados
        /// </summary>
        /// <returns>Lista dos produtos</returns>
        public List<string> ListProducts()
        {
            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.ListProducts();
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        #endregion

        #region Instances

        /// <summary>
        /// Verifica se uma instância está iniciada
        /// </summary>
        /// <param name="productKey">Nome do produto</param>
        /// <param name="instanceKey">Chave da instância</param>
        /// <returns></returns>
        public bool IsInstanceStarted(string productKey, string instanceKey)
        {
            if (string.IsNullOrEmpty(productKey))
                throw new ArgumentNullException("productKey");
            if (string.IsNullOrEmpty(instanceKey))
                throw new ArgumentNullException("instanceKey");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.IsInstanceStarted(productKey, instanceKey);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Inicia uma instância do produto
        /// </summary>
        /// <param name="productKey">Nome do produto</param>
        /// <param name="instanceKey">Chave da instância</param>
        /// <returns></returns>
        public bool StartInstance(string productKey, string instanceKey)
        {
            if (string.IsNullOrEmpty(productKey))
                throw new ArgumentNullException("productKey");
            if (string.IsNullOrEmpty(instanceKey))
                throw new ArgumentNullException("instanceKey");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.StartInstance(productKey, instanceKey);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Para uma instância do produto
        /// </summary>
        /// <param name="productKey">Nome do produto</param>
        /// <param name="instanceKey">Chave da instância</param>
        /// <returns></returns>
        public bool StopInstance(string productKey, string instanceKey)
        {
            if (string.IsNullOrEmpty(productKey))
                throw new ArgumentNullException("productKey");
            if (string.IsNullOrEmpty(instanceKey))
                throw new ArgumentNullException("instanceKey");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.StopInstance(productKey, instanceKey);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Reinicia uma instância do produto
        /// </summary>
        /// <param name="productKey">Nome do produto</param>
        /// <param name="instanceKey">Chave da instância</param>
        /// <returns></returns>
        public bool RestartInstance(string productKey, string instanceKey)
        {
            if (string.IsNullOrEmpty(productKey))
                throw new ArgumentNullException("productKey");
            if (string.IsNullOrEmpty(instanceKey))
                throw new ArgumentNullException("instanceKey");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.RestartInstance(productKey, instanceKey);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Adiciona uma instância
        /// </summary>
        /// <param name="productName">Nome do produto</param>
        /// <param name="instanceName">Nome da instância</param>
        /// <param name="instanceAddress">Endereço da instância</param>
        /// <param name="processPath">Caminho dos processos</param>
        /// <param name="stsAuthorityCertificateName">Nome do certificado de STS</param>
        /// <param name="serviceCertificateName">Nome do certificado de serviços</param>
        /// <returns>true se conseguiu adicionar, false se instância já existe</returns>
        public bool AddInstance(string productName,
                                string instanceName,
                                string instanceAddress,
                                string processPath,
                                string stsAuthorityCertificateName,
                                string serviceCertificateName)
        {
            if (string.IsNullOrEmpty(productName))
                throw new ArgumentNullException("productName");
            if (string.IsNullOrEmpty(instanceName))
                throw new ArgumentNullException("instanceName");
            if (string.IsNullOrEmpty(instanceAddress))
                throw new ArgumentNullException("instanceAddress");
            if (string.IsNullOrEmpty(processPath))
                throw new ArgumentNullException("processPath");
            if (string.IsNullOrEmpty(stsAuthorityCertificateName))
                throw new ArgumentNullException("stsAuthorityCertificateName");
            if (string.IsNullOrEmpty(serviceCertificateName))
                throw new ArgumentNullException("serviceCertificateName");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.AddInstance(productName,
                                         instanceName,
                                         instanceAddress,
                                         processPath,
                                         stsAuthorityCertificateName,
                                         serviceCertificateName);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Adiciona uma instância
        /// </summary>
        /// <param name="productName">Nome do produto</param>
        /// <param name="instanceName">Nome da instância</param>
        /// <param name="instanceAddress">Endereço da instância</param>
        /// <param name="processPath">Caminho dos processos</param>
        /// <param name="stsAuthorityCertificateName">Nome do certificado de STS</param>
        /// <param name="serviceCertificateName">Nome do certificado de serviços</param>
        /// <param name="inteligenceModules">Inteligence modules</param>
        /// <returns>true se conseguiu adicionar, false se instância já existe</returns>
        public bool AddInstance(string productName,
                                string instanceName,
                                string instanceAddress,
                                string processPath,
                                string stsAuthorityCertificateName,
                                string serviceCertificateName,
                                List<InteligenceModuleEntity> inteligenceModules)
        {
            if (string.IsNullOrEmpty(productName))
                throw new ArgumentNullException("productName");
            if (string.IsNullOrEmpty(instanceName))
                throw new ArgumentNullException("instanceName");
            if (string.IsNullOrEmpty(instanceAddress))
                throw new ArgumentNullException("instanceAddress");
            if (string.IsNullOrEmpty(processPath))
                throw new ArgumentNullException("processPath");
            if (string.IsNullOrEmpty(stsAuthorityCertificateName))
                throw new ArgumentNullException("stsAuthorityCertificateName");
            if (string.IsNullOrEmpty(serviceCertificateName))
                throw new ArgumentNullException("serviceCertificateName");
            if (inteligenceModules == null || inteligenceModules.Count == 0)
                throw new ArgumentNullException("inteligenceModules");


            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.AddInstance(productName,
                                         instanceName,
                                         instanceAddress,
                                         processPath,
                                         stsAuthorityCertificateName,
                                         serviceCertificateName,
                                         inteligenceModules);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Exclui uma instância
        /// </summary>
        /// <param name="productName">Nome do produto</param>
        /// <param name="instanceName">Nome da instância</param>
        /// <returns>true se conseguiu excluir, false se a instância não existe</returns>
        public bool RemoveInstance(string productName, string instanceName)
        {
            if (string.IsNullOrEmpty(productName))
                throw new ArgumentNullException("productName");
            if (string.IsNullOrEmpty(instanceName))
                throw new ArgumentNullException("instanceName");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.RemoveInstance(productName, instanceName);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Lista as instâncias de um produto
        /// </summary>
        /// <param name="productName">Nome do produto</param>
        /// <returns>Lista de instâncias</returns>
        public List<InstanceEntity> ListInstances(string productName)
        {
            if (string.IsNullOrEmpty(productName))
                throw new ArgumentNullException("productName");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.ListInstances(productName);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        #endregion

        #region Process

        /// <summary>
        /// Verifica se um processo está iniciado
        /// </summary>
        /// <param name="productKey">Nome do produto</param>
        /// <param name="instanceKey">Chave da instância</param>
        /// <param name="processId">Id do processo</param>
        /// <returns></returns>
        public bool IsProcessStarted(string productKey, string instanceKey, int processId)
        {
            if (string.IsNullOrEmpty(productKey))
                throw new ArgumentNullException("productKey");
            if (string.IsNullOrEmpty(instanceKey))
                throw new ArgumentNullException("instanceKey");
            if (processId < 0)
                throw new ArgumentOutOfRangeException("processId");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.IsProcessStarted(productKey, instanceKey, processId);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Inicia um processo auto-start
        /// </summary>
        /// <param name="productKey">Nome do produto</param>
        /// <param name="instanceKey">Chave da instância</param>
        /// <param name="processId">Id do processo</param>
        /// <returns></returns>
        public bool StartProcess(string productKey, string instanceKey, int processId)
        {
            if (string.IsNullOrEmpty(productKey))
                throw new ArgumentNullException("productKey");
            if (string.IsNullOrEmpty(instanceKey))
                throw new ArgumentNullException("instanceKey");
            if (processId < 0)
                throw new ArgumentOutOfRangeException("processId");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.StartProcess(productKey, instanceKey, processId);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        /// <summary>
        /// Aborta um processo
        /// </summary>
        /// <param name="productKey">Nome do produto</param>
        /// <param name="instanceKey">Chave da instância</param>
        /// <param name="processId">Id do processo</param>
        /// <returns></returns>
        public bool StopProcess(string productKey, string instanceKey, int processId)
        {
            if (string.IsNullOrEmpty(productKey))
                throw new ArgumentNullException("productKey");
            if (string.IsNullOrEmpty(instanceKey))
                throw new ArgumentNullException("instanceKey");
            if (processId < 0)
                throw new ArgumentOutOfRangeException("processId");

            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.StopProcess(productKey, instanceKey, processId);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        public bool AddProcess(string productName, string instanceName, ProcessEntity process)
        {
            if (string.IsNullOrEmpty(productName))
                throw new ArgumentNullException("productName");
            if (string.IsNullOrEmpty(instanceName))
                throw new ArgumentNullException("instanceName");
            if (process == null)
                throw new ArgumentNullException("process");


            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.AddProcess(productName, instanceName, process);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        public bool RemoveProcess(string productName, string instanceName, int processId)
        {
            if (string.IsNullOrEmpty(productName))
                throw new ArgumentNullException("productName");
            if (string.IsNullOrEmpty(instanceName))
                throw new ArgumentNullException("instanceName");
            if (processId <= 0)
                throw new ArgumentOutOfRangeException("processId");


            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.RemoveProcess(productName, instanceName, processId);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        public List<ProcessEntity> ListProcesses(string productName, string instanceName)
        {
            if (string.IsNullOrEmpty(productName))
                throw new ArgumentNullException("productName");
            if (string.IsNullOrEmpty(instanceName))
                throw new ArgumentNullException("instanceName");


            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.ListProcesses(productName, instanceName);
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }

        #endregion

        /// <summary>
        /// Retorna a lista de inteligence modules
        /// </summary>
        /// <param name="dataFilesDirPath"></param>
        public List<InteligenceModuleEntity> ListInteligenceModules()
        {
            IInteligenceManagerService proxy = null;
            try
            {
                proxy = GetInteligenceManagerServiceProxy();

                return proxy.ListInteligenceModules();
            }
            finally
            {
                try
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Close();
                }
                catch
                {
                    if (proxy != null && proxy is IClientChannel)
                        ((IClientChannel)proxy).Abort();
                }
            }
        }
    }
}
